"""
Python代码处理器 - 专门处理Python文件的优化
"""

import ast
import re
import os
from pathlib import Path
from typing import Dict, Any, List, Tuple, Set, Optional

class PythonHandler:
    """Python代码处理器类"""
    
    def __init__(self, path: Path, config: Dict[str, Any]):
        self.path = path
        self.config = config
        self.content = None
        self.lines = []
        self.imports = set()
        self.functions = []
        self.classes = []
        self.ast_tree = None
    
    def load(self) -> bool:
        """加载文件内容"""
        try:
            with open(self.path, 'r', encoding='utf-8') as f:
                self.content = f.read()
                self.lines = self.content.splitlines()
            return True
        except Exception as e:
            print(f"无法加载文件 {self.path}: {e}")
            return False
    
    def save(self, path: Optional[str] = None) -> bool:
        """保存文件内容"""
        save_path = Path(path) if path else self.path
        try:
            save_path.parent.mkdir(parents=True, exist_ok=True)
            with open(save_path, 'w', encoding='utf-8') as f:
                if self.content:
                    f.write(self.content)
                else:
                    f.write('\n'.join(self.lines))
            return True
        except Exception as e:
            print(f"无法保存文件 {save_path}: {e}")
            return False
    
    def analyze(self) -> bool:
        """分析Python代码"""
        if not self.load():
            return False
            
        try:
            self.ast_tree = ast.parse(self.content)
            
            # 提取导入
            for node in ast.walk(self.ast_tree):
                if isinstance(node, ast.Import):
                    for name in node.names:
                        self.imports.add(name.name)
                elif isinstance(node, ast.ImportFrom):
                    module = node.module or ''
                    for name in node.names:
                        self.imports.add(f"{module}.{name.name}")
                
                # 提取函数
                elif isinstance(node, ast.FunctionDef):
                    self.functions.append({
                        'name': node.name,
                        'line': node.lineno,
                        'end_line': node.end_lineno,
                        'args': [arg.arg for arg in node.args.args],
                        'is_async': isinstance(node, ast.AsyncFunctionDef)
                    })
                
                # 提取类
                elif isinstance(node, ast.ClassDef):
                    methods = []
                    for item in node.body:
                        if isinstance(item, ast.FunctionDef):
                            methods.append(item.name)
                    
                    self.classes.append({
                        'name': node.name,
                        'line': node.lineno,
                        'end_line': node.end_lineno,
                        'methods': methods,
                        'bases': [base.id for base in node.bases if isinstance(base, ast.Name)]
                    })
            
            return True
        
        except SyntaxError as e:
            print(f"Python语法错误 {self.path}: {e}")
            return False
        except Exception as e:
            print(f"分析Python文件时出错 {self.path}: {e}")
            return False
    
    def needs_splitting(self) -> bool:
        """检查文件是否需要拆分"""
        return len(self.lines) > self.config['split_threshold']
    
    def split_file(self) -> List[Tuple[str, str]]:
        """拆分大型Python文件"""
        if not self.needs_splitting() or not self.ast_tree:
            return []
        
        # 收集所有导入语句
        imports = []
        for node in ast.iter_child_nodes(self.ast_tree):
            if isinstance(node, (ast.Import, ast.ImportFrom)):
                import_lines = self.lines[node.lineno-1:node.end_lineno]
                imports.extend(import_lines)
        
        # 收集类和函数
        classes = []
        functions = []
        
        for node in ast.iter_child_nodes(self.ast_tree):
            if isinstance(node, ast.ClassDef):
                class_lines = self.lines[node.lineno-1:node.end_lineno]
                classes.append((node.name, '\n'.join(class_lines)))
            elif isinstance(node, ast.FunctionDef) and node.name != '__init__':
                func_lines = self.lines[node.lineno-1:node.end_lineno]
                functions.append((node.name, '\n'.join(func_lines)))
        
        # 创建拆分文件
        result = []
        
        # 创建主文件
        main_content = '\n'.join(imports) + '\n\n'
        
        # 添加类导入
        for class_name, _ in classes:
            main_content += f"from .{class_name.lower()} import {class_name}\n"
        
        # 添加函数导入
        if functions:
            main_content += f"from .functions import {', '.join(func_name for func_name, _ in functions)}\n"
        
        # 添加__all__导出
        main_content += '\n\n__all__ = [\n'
        for class_name, _ in classes:
            main_content += f"    '{class_name}',\n"
        for func_name, _ in functions:
            main_content += f"    '{func_name}',\n"
        main_content += ']\n'
        
        result.append((self.path.stem + '.py', main_content))
        
        # 创建类文件
        for class_name, class_content in classes:
            class_file = f"{class_name.lower()}.py"
            class_file_content = '\n'.join(imports) + '\n\n' + class_content
            result.append((class_file, class_file_content))
        
        # 创建函数文件
        if functions:
            functions_content = '\n'.join(imports) + '\n\n'
            functions_content += '\n\n'.join(func_content for _, func_content in functions)
            result.append(('functions.py', functions_content))
        
        return result
    
    def add_async_support(self) -> bool:
        """添加异步支持"""
        if not self.content:
            return False
            
        # 添加异步导入
        if 'import asyncio' not in self.content:
            self.content = 'import asyncio\n' + self.content
        
        # 将适合的函数转换为异步函数
        modified_content = self.content
        for func in self.functions:
            if not func['is_async'] and self._can_be_async(func):
                # 找到函数定义行
                func_line = self.lines[func['line'] - 1]
                # 添加async关键字
                if 'def ' in func_line:
                    new_func_line = func_line.replace('def ', 'async def ')
                    modified_content = modified_content.replace(func_line, new_func_line)
        
        self.content = modified_content
        return True
    
    def _can_be_async(self, func: Dict) -> bool:
        """判断函数是否适合转换为异步"""
        # 这里可以添加更复杂的逻辑来判断函数是否适合异步
        # 例如检查是否包含I/O操作、网络请求等
        name = func['name'].lower()
        return any(keyword in name for keyword in ['get', 'fetch', 'download', 'load', 'read', 'write', 'save', 'process'])
    
    def add_performance_monitoring(self) -> bool:
        """添加性能监控代码"""
        if not self.content:
            return False
            
        # 添加时间模块导入
        if 'import time' not in self.content:
            self.content = 'import time\n' + self.content
        
        # 为每个函数添加性能监控
        modified_content = self.content
        for func in self.functions:
            # 找到函数体的开始和结束
            func_start_line = self.lines[func['line'] - 1]
            indent = len(func_start_line) - len(func_start_line.lstrip())
            indent_str = ' ' * indent
            
            # 在函数开始处添加计时代码
            timing_start = f"\n{indent_str}    start_time = time.time()\n"
            
            # 在函数结束处添加计时结束和日志代码
            timing_end = (
                f"\n{indent_str}    end_time = time.time()\n"
                f"{indent_str}    print(f\"函数 {func['name']} 执行时间: {{end_time - start_time:.4f}}秒\")\n"
            )
            
            # 找到函数体的第一行和最后一行
            func_body_start = None
            for i in range(func['line'], func['end_line']):
                line = self.lines[i - 1]
                if ':' in line and line.rstrip().endswith(':'):
                    func_body_start = i
                    break
            
            if func_body_start:
                # 在函数体开始处插入计时开始代码
                insert_pos = self.content.find(self.lines[func_body_start])
                if insert_pos != -1:
                    modified_content = modified_content[:insert_pos + len(self.lines[func_body_start])] + timing_start + modified_content[insert_pos + len(self.lines[func_body_start]):]
                
                # 在函数体结束前插入计时结束代码
                # 这里简化处理，实际上需要更复杂的逻辑来处理所有return语句
                func_end_pos = self.content.find(self.lines[func['end_line'] - 1])
                if func_end_pos != -1:
                    modified_content = modified_content[:func_end_pos] + timing_end + modified_content[func_end_pos:]
        
        self.content = modified_content
        return True
    
    def optimize(self) -> bool:
        """优化Python代码"""
        if not self.analyze():
            return False
            
        # 检查是否需要拆分文件
        if self.needs_splitting():
            split_files = self.split_file()
            if split_files:
                # 创建新的目录来存放拆分后的文件
                module_dir = self.path.parent / self.path.stem
                module_dir.mkdir(exist_ok=True)
                
                # 创建__init__.py文件
                with open(module_dir / '__init__.py', 'w', encoding='utf-8') as f:
                    f.write(f"from .{self.path.stem} import *\n")
                
                # 保存拆分后的文件
                for filename, content in split_files:
                    with open(module_dir / filename, 'w', encoding='utf-8') as f:
                        f.write(content)
                
                print(f"文件已拆分到目录: {module_dir}")
                return True
        
        # 添加异步支持
        if self.config['add_async']:
            self.add_async_support()
        
        # 添加性能监控
        if self.config['monitor']:
            self.add_performance_monitoring()
        
        # 保存修改后的文件
        return self.save()